/* 8911106 302933981 Ofri Keidar */

/******************************************************************************
* Student Name: Ofri Keidar
* Exercise Name: Ex6
* File Description: Template class MyAuto_ptr. Represents an auto-ptr for
* 					T objects. When MyAuto_ptr objet is destroyed, it frees the
* 					pointed data
******************************************************************************/


#ifndef MYSMART_PTR_H_
#define MYSMART_PTR_H_

template <typename T> class MyAuto_ptr {
private:
	T* m_dataPtr; // pointer to object of type T

public:
	/***************************************************************************************
	* function name: MyAuto_ptr(T* data = NULL)
	* The Input: Pointer to T object. Default value is NULL
	* The output: None
	* The Function operation: Creates a new MyAuto_ptr object pointing at given T object
	***************************************************************************************/
	MyAuto_ptr(T* data = NULL) {m_dataPtr = data;}

	/***************************************************************************************
	* function name: MyAuto_ptr(const MyAuto_ptr& ptrToCopy)
	* The Input: MyAuto_ptr object to be copied
	* The output: None
	* The Function operation: Creates a new MyAuto_ptr object pointing at given pinter's T object
	***************************************************************************************/
	MyAuto_ptr(const MyAuto_ptr& ptrToCopy) {m_dataPtr = ptrToCopy.m_dataPtr;}

	/***************************************************************************************
	* function name: ~MyAuto_ptr()
	* The Input: None
	* The output: None
	* The Function operation: Deletes pointed data
	***************************************************************************************/
	~MyAuto_ptr() {delete m_dataPtr;}

	/***************************************************************************************
	* function name: MyAuto_ptr<T>& operator=(MyAuto_ptr<T>& otherPtr)
	* The Input: MyAuto_ptr object that its value should be assigned
	* The output: Reference to activating object
	* The Function operation: Deletes pointed data, sets m_dataPtr to given MyAuto_ptr's
	* 						  pointed data and sets given pointer's to NULL
	***************************************************************************************/
	MyAuto_ptr<T>& operator=(MyAuto_ptr<T>& otherPtr) {
		if (this != &otherPtr) { // check if not self assignment
			delete m_dataPtr; // delete pointed data
			m_dataPtr = otherPtr.m_dataPtr; // point at given pointer's data
			otherPtr.m_dataPtr = NULL; // set given pointer's data to NULL
		}
		return *this; // return reference to activating object
	}

	/***************************************************************************************
	* function name: T& operator*() const
	* The Input: None
	* The output: Reference to pointed T object
	* The Function operation: Returns pointed value by T data pointer attribute.
	* 				          Method does not change the object
	***************************************************************************************/
	T& operator*() const {return *m_dataPtr;}

	/***************************************************************************************
	* function name: T* getPointer() const
	* The Input: None
	* The output: Pointer to the T object
	* The Function operation: Returns T data pointer attribute.
	* 				          Method does not chagne the object
	***************************************************************************************/
	T* getPointer() const {return m_dataPtr;}
};

#endif
